﻿using System;
using System.Windows;
using System.Windows.Input;
using System.Collections.ObjectModel;
using DDU.DataModel;
using System.IO.IsolatedStorage;
using System.Linq;
using DDU.Library;
using Microsoft.Phone.Tasks;
using System.IO;

namespace DDU.ViewModel
{
    public class BookEditViewModel : MainViewModel
    {
        #region Constructors
        PhotoChooserTask photoChooser = new PhotoChooserTask() { ShowCamera = true };
        CameraCaptureTask cameraCapture = new CameraCaptureTask();

        public BookEditViewModel()
        {

            photoChooser.Completed -= PhotoChooser_Completed;
            photoChooser.Completed += PhotoChooser_Completed;

            cameraCapture.Completed -= cameraCapture_Completed;
            cameraCapture.Completed += cameraCapture_Completed;
        } 
        #endregion

        #region Properties
        private string guid;
        public string Guid
        {
            get { return guid; }
            set
            {
                guid = value;
                RaisePropertyChanged(() => Guid);
                if (!string.IsNullOrWhiteSpace(Guid))
                {
                    BookToEdit = Database.CollectionOfBooks.FirstOrDefault(b => b.Guid == Guid);
                    if (BookToEdit != null)
                    {
                        SelectedSemester = Database.CollectionOfSemesters.FirstOrDefault(s => s.Guid == BookToEdit.SemesterGuid);
                    }
                    RaisePropertyChanged(() => UpdateCommand);
                    RaisePropertyChanged(() => DeleteCommand);
                }
            }
        }

        public bool CanUpdate
        {
            get
            {
                //return true;
                return IsDesignMode ? true : SelectedSemester != null;
            }
        }

        private SemesterInfo selectedSemester;
        public SemesterInfo SelectedSemester
        {
            get { return selectedSemester; }
            set
            {
                selectedSemester = value;
                RaisePropertyChanged(() => SelectedSemester);
                RaisePropertyChanged(() => CanUpdate);
                BookToEdit.SemesterGuid = SelectedSemester.Guid;
                RaisePropertyChanged(() => BookToEdit);
            }
        }

        private BookInfo bookToEdit;
        public BookInfo BookToEdit
        {
            get { return bookToEdit; }
            set
            {
                bookToEdit = value;
                RaisePropertyChanged(() => BookToEdit);
                RaisePropertyChanged(() => UpdateCommand);
                BookToEdit.ValueChanged -= BookToEdit_ValueChanged;
                BookToEdit.ValueChanged += BookToEdit_ValueChanged;
            }
        }

        private Visibility contentPanelVisibility = Visibility.Visible;
        public Visibility ContentPanelVisibility
        {
            get { return contentPanelVisibility; }
            set
            {
                contentPanelVisibility = value;
                RaisePropertyChanged(() => ContentPanelVisibility);
            }
        }

        private Visibility galleryPanelVisibility = Visibility.Collapsed;
        public Visibility GalleryPanelVisibility
        {
            get { return galleryPanelVisibility; }
            set
            {
                galleryPanelVisibility = value;
                RaisePropertyChanged(() => GalleryPanelVisibility);
            }
        }

        public ObservableCollection<StoredBookCoverInfo> StoredCoverImages
        {
            get
            {
                if (IsDesignMode)
                {
                    return null;
                }
                using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    return new ObservableCollection<StoredBookCoverInfo>(store.GetFileNames(ConstKeys.BookDirectoryName + "\\*.*").Select(s => new StoredBookCoverInfo(ConstKeys.BookDirectoryName + "\\" + s)));
                }
            }
        }

        private StoredBookCoverInfo selectedCover;
        public StoredBookCoverInfo SelectedCover
        {
            get { return selectedCover; }
            set
            {
                selectedCover = value;
                RaisePropertyChanged(() => SelectedCover);
                RaisePropertyChanged(() => SelectedOKCommand);
            }
        } 
        #endregion

        #region Event
        void BookToEdit_ValueChanged(object sender, PropertyArgs e)
        {
            RaisePropertyChanged(() => UpdateCommand);
        }

        void cameraCapture_Completed(object sender, PhotoResult e)
        {
            SavePhoto(e);
        }

        void PhotoChooser_Completed(object sender, PhotoResult e)
        {
            SavePhoto(e);
        }

        void SavePhoto(PhotoResult e)
        {
            if (e.TaskResult == TaskResult.OK)
            {
                using (BinaryReader reader = new BinaryReader(e.ChosenPhoto))
                {
                    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        string fileName = ConstKeys.BookDirectoryName + "\\" + DateTime.Now.Ticks + Path.GetExtension(e.OriginalFileName);

                        if (store.FileExists(fileName))
                        {
                            store.DeleteFile(fileName);
                        }

                        using (IsolatedStorageFileStream fileStream = store.OpenFile(fileName, FileMode.OpenOrCreate, FileAccess.Write))
                        {
                            using (BinaryWriter writer = new BinaryWriter(fileStream))
                            {
                                writer.Write(reader.ReadBytes(Convert.ToInt32(e.ChosenPhoto.Length)));
                            }

                            fileStream.Close();
                            fileStream.Dispose();
                        }

                        BookToEdit.Image = fileName;
                        RaisePropertyChanged(() => BookToEdit);
                    }
                }
            }
        }

        void Update(BookInfo entity)
        {
            BookInfo item = Database.CollectionOfBooks.FirstOrDefault(b => b.Guid == Guid);
            item = entity;
            Submit();
        }

        void Remove(BookInfo entity)
        {
            Database.CollectionOfBooks.DeleteOnSubmit(entity);
            Submit();
        }
        #endregion

        #region Commands
        public ICommand BarcodeCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return false; }
                };
            }
        }

        public ICommand ChooseCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate { photoChooser.Show(); }
                };
            }
        }

        public ICommand CameraCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate { cameraCapture.Show(); }
                };
            }
        }

        public ICommand UpdateCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return BookToEdit!=null && !string.IsNullOrWhiteSpace(BookToEdit.Title) && !string.IsNullOrWhiteSpace(BookToEdit.Image) && CanUpdate; },
                    ExecuteCallback = delegate
                    {
                        Update(BookToEdit);
                        Navigate(BackUri);
                    }
                };
            }
        }

        public ICommand CancelCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate
                    {
                        if (BackUri != null)
                        {
                            Navigate(BackUri);
                        }
                    }
                };
            }
        }

        public ICommand DeleteCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return BookToEdit != null; },
                    ExecuteCallback = delegate
                    {
                        if (MessageBox.Show("确定要删除这条信息吗？", "删除确认", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                        {
                            Remove(BookToEdit);
                            Navigate(BackUri);
                        }
                    }
                };
            }
        }

        public ICommand OpenGalleryCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate
                    {
                        ContentPanelVisibility = Visibility.Collapsed;
                        GalleryPanelVisibility = Visibility.Visible;
                    }
                };
            }
        }

        public ICommand SelectedOKCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return SelectedCover != null; },
                    ExecuteCallback = delegate {
                        BookToEdit.Image = SelectedCover.FileName;
                        HideGalleryCommand.Execute(null);
                    }
                };
            }
        }

        public ICommand HideGalleryCommand
        {
            get
            {
                return new GenericCommand()
                {
                    //CanExecuteCallback = delegate { return SelectedCover != null; },
                    ExecuteCallback = delegate
                    {
                        ContentPanelVisibility = Visibility.Visible;
                        GalleryPanelVisibility = Visibility.Collapsed;
                        SelectedCover = null;
                        RaisePropertyChanged(() => SelectedCover);
                        RaisePropertyChanged(() => SelectedOKCommand);
                    }
                };
            }
        }
        #endregion
    }
}
